import os
import secrets
from typing import Any, Dict, List, Optional, Union

from pydantic import AnyHttpUrl, ConfigDict, Field, field_validator
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    """应用配置"""

    # ==================================
    # 基础配置
    # ==================================
    PROJECT_NAME: str = "FastAPI Template"
    PROJECT_DESCRIPTION: str = "A modern FastAPI project template"
    VERSION: str = "0.0.1"
    TIMEZONE: str = "Asia/Shanghai"
    FRONTEND_URL: str = "http://localhost:3000"  # 前端应用URL
    BASE_DIR: str = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    COMPANY_NAME: str = "Your Company"

    # ==================================
    # 安全配置
    # ==================================
    DEBUG: bool = True
    API_V1_STR: str = "/api/v1"
    SECRET_KEY: str = Field(default_factory=lambda: secrets.token_urlsafe(32))
    ENABLE_CAPTCHA: bool = False

    # JWT配置
    JWT_ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    REFRESH_TOKEN_EXPIRE_MINUTES: int = 7 * 24 * 60
    PASSWORD_RESET_TOKEN_EXPIRE_MINUTES: int = 30
    ALGORITHM: str = "HS256"
    # CORS配置
    BACKEND_CORS_ORIGINS: Union[str, List[AnyHttpUrl]] = []

    @field_validator("BACKEND_CORS_ORIGINS", mode="before")
    def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
        if isinstance(v, str) and not v.startswith("["):
            return [i.strip() for i in v.split(",")]
        elif isinstance(v, (list, str)):
            return v
        return []

    # ==================================
    # 数据存储
    # ==================================
    # Database
    DATABASE_URL: str = "sqlite://db.sqlite3"

    # Redis配置
    REDIS_HOST: str = "localhost"
    REDIS_PORT: int = 6379
    REDIS_PASSWORD: Optional[str] = None
    DEFAULT_REDIS_DB: int = 0
    REDIS_SSL: bool = False

    # ==================================
    # 邮件服务
    # ==================================
    # SMTP服务器配置
    SMTP_TLS: bool = True
    SMTP_PORT: int = 587
    SMTP_HOST: str = "smtp.gmail.com"
    SMTP_USERNAME: str = ""
    SMTP_PASSWORD: str = ""

    # 邮件基本设置
    EMAIL_SENDER_NAME: str = "System Notification"
    EMAIL_SENDER_ADDRESS: str = "noreply@example.com"
    DEFAULT_FROM_EMAIL: str = "noreply@example.com"

    # 验证码配置
    VERIFY_CODE_LENGTH: int = 6  # 验证码长度
    VERIFY_CODE_EXPIRE_MINUTES: int = 10  # 验证码有效期(分钟)
    VERIFY_CODE_LIMIT_MINUTES: int = 1  # 验证码发送限制时间(分钟)

    # ==================================
    # 任务调度系统
    # ==================================
    # Scheduler Core
    TASK_REDIS_DB: int = 1
    SCHEDULER_INTERVAL: float = 1.0
    SCHEDULER_MAX_INSTANCES: int = 1
    MAX_REDIS_MEMORY: int = 1024

    # Worker Settings
    SCHEDULER_WORKER_NUM: int = 3
    SCHEDULER_WORKER_TIMEOUT: int = 600
    SCHEDULER_MAX_QUEUE_SIZE: int = 10000

    # ==================================
    # 其他配置
    # ==================================
    # 邀请码设置
    INVITE_CODE_MAX_USAGE: int = 5  # 邀请码最大使用次数

    # ==================================
    # GitHub OAuth配置
    # ==================================
    GITHUB_CLIENT_ID: str = ""
    GITHUB_CLIENT_SECRET: str = ""
    GITHUB_CALLBACK_URL: str = "http://localhost:8000/api/auth/github/callback"

    # ==================================
    # Cloudflare Turnstile配置
    # ==================================
    TURNSTILE_SECRET_KEY: str = ""

    # ==================================
    # 短信服务配置
    # ==================================
    SMS_PROVIDER: str = "aliyun"
    REGION: str = "cn-hangzhou"
    SMS_SIGN_NAME: str = ""
    SMS_TEMPLATE_ID: str = ""
    ACCESS_KEY: str = ""
    ACCESS_SECRET: str = ""
    SDK_APP_ID: Optional[str] = None  # 仅腾讯云需要

    model_config = ConfigDict(case_sensitive=True, env_file=".env.dev", env_file_encoding="utf-8")


settings = Settings()

TORTOISE_ORM: Dict[str, Any] = {
    "connections": {"default": settings.DATABASE_URL},
    "apps": {
        "models": {
            "models": ["app.models", "aerich.models"],
            "default_connection": "default",
        },
    },
    "use_tz": False,
    "timezone": settings.TIMEZONE,
    "generate_schemas": False,
}
